package com.yunyao.dao.service.bamu.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yunyao.common.constant.enums.DataDeletedStatus;
import com.yunyao.dao.mapper.BamuMaterialCategoryMapper;
import com.yunyao.dao.mapper.BamuMaterialMapper;
import com.yunyao.dao.model.BamuMaterial;
import com.yunyao.dao.model.BamuMaterialCategory;
import com.yunyao.dao.service.bamu.IBamuMaterialService;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * <p>
 * 材料信息 服务实现类
 * </p>
 *
 * @author xingjishuai
 * @since 2024-07-02
 */
@Service
public class BamuMaterialServiceImpl extends ServiceImpl<BamuMaterialMapper, BamuMaterial> implements IBamuMaterialService {
    @Autowired
    private BamuMaterialCategoryMapper bamuMaterialCategoryMapper;

    /**
     * 根据分页参数和查询条件获取材料列表
     *
     * @param pageIndex       当前页码
     * @param pageSize        每页显示数量
     * @param materialCode    材料编码
     * @param materialName    材料名称
     * @param materialSpecifications 材料规格
     * @param materialCategoryId     材料类别ID
     * @return 分页材料列表
     */
    @Override
    public IPage<BamuMaterial> pageList(Long pageIndex, Long pageSize, String materialCode,
                                        String materialName, String materialSpecifications,
                                        String materialCategoryId) {
        // 判断材料类别ID是否为最后一级
        boolean lastLevel = isLastLevel(materialCategoryId);
        String newAncestors = StringUtils.EMPTY;
        if (!lastLevel) {
            // 如果不是最后一级，则获取完整的祖先类别ID
            newAncestors = getMaterialCategoryId(materialCategoryId);
            // 清空材料类别ID，以便查询所有相关材料
            materialCategoryId = StringUtils.EMPTY;
        }
        // 查询满足条件的总页数
        long pageCount = baseMapper.pageCount(newAncestors, materialCode, materialName,
                materialSpecifications,
                materialCategoryId);
        // 如果总页数为0，则直接返回空的分页对象
        if (pageCount == 0) {
            return new Page<>(pageIndex, pageSize, pageCount);
        }
        // 计算当前页码对应的数据起始索引
        long index = pageIndex <= 1 ? 0 : (pageIndex - 1) * pageSize;
        // 根据起始索引和每页显示数量获取分页材料列表
        List<BamuMaterial> bamuMaterialList = baseMapper.pageList(newAncestors,
                materialCode, materialName, materialSpecifications,
                materialCategoryId
                , index, pageSize);
        // 创建并设置分页对象的属性
        IPage<BamuMaterial> page = new Page<>(pageIndex, pageSize, pageCount);
        page.setRecords(bamuMaterialList);
        // 计算总页数并设置
        page.setPages(pageCount % pageSize == 0 ? pageCount / pageSize : pageCount / pageSize + 1);
        return page;
    }


    /**
     * 根据材料名称和规格获取材料信息
     * 此方法通过材料名称和规格来查询材料信息，确保查询的准确性
     *
     * @param materialName 材料名称，用于定位特定材料
     * @param materialSpecs 材料规格，用于精确匹配材料
     * @return 如果找到对应的材料信息，则返回BamuMaterial对象；否则返回null
     *
     * 注意：此方法依赖于材料名称和规格的唯一性
     */
    @Override
    public BamuMaterial getByNameAndSpecs(String materialName, String materialSpecs) {
        // 检查参数是否有效，如果材料名称或规格为空或null，则直接返回null
        if (StringUtils.isBlank(materialName) || StringUtils.isBlank(materialSpecs)) {
            return null;
        }
        // 构建查询条件
        LambdaQueryWrapper<BamuMaterial> wrapper = new LambdaQueryWrapper<>();
        // 设置材料名称的查询条件
        wrapper.eq(BamuMaterial::getMaterialName, materialName);
        // 设置材料规格的查询条件
        wrapper.eq(BamuMaterial::getMaterialSpecifications, materialSpecs);
        // 排除已被删除的材料
        wrapper.eq(BamuMaterial::getIsDeleted, DataDeletedStatus.NO.getType()).orderByDesc(BamuMaterial::getCreatedAt);
        // 执行查询并返回结果
        List<BamuMaterial> bamuMaterialList = baseMapper.selectList(wrapper);
        if (CollectionUtils.isEmpty(bamuMaterialList)) {
            return null;
        }
        return bamuMaterialList.get(0);
    }

    /**
     * 根据材料类别ID获取其祖先类别ID字符串
     * 如果传入的材料类别ID为空或找不到对应的类别信息，返回空字符串
     * 找到对应的类别信息时，返回包含该类别及其祖先类别的ID字符串，以","分隔
     *
     * @param materialCategoryId 材料类别ID
     * @return 包含祖先类别ID的字符串
     */
    private String getMaterialCategoryId(String materialCategoryId) {
        // 检查材料类别ID是否为空或仅含空格，如果是，返回空字符串
        if (StringUtils.isBlank(materialCategoryId)) {
            return StringUtils.EMPTY;
        }
        // 初始化查询条件封装对象
        LambdaQueryWrapper<BamuMaterialCategory> wrapper = new LambdaQueryWrapper<>();
        // 设置查询条件：根据ID和未被删除的状态
        wrapper.eq(BamuMaterialCategory::getId, materialCategoryId);
        wrapper.eq(BamuMaterialCategory::getIsDeleted, DataDeletedStatus.NO.getType());
        // 执行查询，获取材料类别信息
        BamuMaterialCategory bamuMaterialCategory = bamuMaterialCategoryMapper.selectOne(wrapper);
        // 如果未找到材料类别信息，返回空字符串
        if (bamuMaterialCategory == null) {
            return StringUtils.EMPTY;
        }
        // 返回包含祖先类别ID和当前类别ID的字符串，用于后续构建完整的类别路径
        return bamuMaterialCategory.getAncestors() + bamuMaterialCategory.getId() + ",";
    }


    /**
     * 判断给定的物料分类ID是否为最底层分类
     *
     * @param materialCategoryId 物料分类ID
     * @return 如果是最底层分类，返回true；否则返回false
     */
    private boolean isLastLevel(String materialCategoryId) {
        // 构建查询条件，查询parentId为给定物料分类ID且未被删除的分类数量
        LambdaQueryWrapper<BamuMaterialCategory> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(BamuMaterialCategory::getParentId, materialCategoryId);
        queryWrapper.eq(BamuMaterialCategory::getIsDeleted, DataDeletedStatus.NO.getType());

        // 执行查询并获取结果数量
        Long selectCount = bamuMaterialCategoryMapper.selectCount(queryWrapper);

        // 如果查询结果为空，说明给定的物料分类ID是最底层分类
        if (selectCount == null) {
            return true;
        }

        // 如果查询结果数量为0，也说明给定的物料分类ID是最底层分类
        return selectCount == 0;
    }

}
